package iterator;
    
 
 import heap.*;
 import columnar.*;
 import global.*;
 import bufmgr.*;
 import diskmgr.*;
 
 
 import java.lang.*;
 import java.io.*;
 
 
  //*open a heapfile and according to the condition expression to get
  //*output file, call get_next to get all tuples
  
 public class FileScan extends  Iterator
 {
   private AttrType[] _in1;
   private short in1_len;
   private short[] s_sizes; 
 //   private Heapfile f;
   private ColumnarFile f;
   private TupleScan tscan;
   private Tuple     tuple1;
   private Tuple    Jtuple;
   private int        t1_size;
   private int nOutFlds;
   private CondExpr[]  OutputFilter;
   public FldSpec[] perm_mat;
   private AttrType[] _Fstype;
   private short[] _Fssize;
 
  
 
   //
    //constructor
    //@param file_name heapfile to be opened
    //@param in1[]  array showing what the attributes of the input fields are. 
    //@param s1_sizes[]  shows the length of the string fields.
    //@param len_in1  number of attributes in the input tuple
    //@param n_out_flds  number of fields in the out tuple
    //@param proj_list  shows what input fields go where in the output tuple
    //@param outFilter  select expressions
    //@exception IOException some I/O fault
    //@exception FileScanException exception from this class
    //@exception TupleUtilsException exception from this class
    //@exception InvalidRelation invalid relation 
    
   public  FileScan (String  file_name,
 		    AttrType in1[],                
 		    short s1_sizes[], 
 		    short     len_in1,              
 		    int n_out_flds,
 		    FldSpec[] proj_list,
 		    CondExpr[]  outFilter ,
 		   int[] target_colnums,
 		   AttrType Fstype[],
 		   short Fssize[]
 		    )
     throws IOException,
 	   FileScanException,
 	   TupleUtilsException, 
 	   InvalidRelation
     {
       _in1 = in1; 
       in1_len = len_in1;
       s_sizes = s1_sizes;
       _Fstype = Fstype;
       _Fssize = Fssize;
       Jtuple =  new Tuple();
       AttrType[] Jtypes = new AttrType[n_out_flds];
       short[]    ts_size;
       ts_size = TupleUtils.setup_op_tuple(Jtuple, Jtypes, in1, len_in1, s1_sizes, proj_list, n_out_flds);
       
       OutputFilter = outFilter;
       perm_mat = proj_list;
       nOutFlds = n_out_flds; 
       tuple1 =  new Tuple();
 
       try {
// 	tuple1.setHdr((short)_in1.length, _in1, s1_sizes);
   //set the header only for the required target column names 	   
    tuple1.setHdr((short)_Fstype.length, _Fstype, _Fssize);
       }catch (Exception e){
 	throw new FileScanException(e, "setHdr() failed");
       }
       t1_size = tuple1.size();
       
       try {
 	 f = new ColumnarFile(file_name,in1_len,_in1);
 	
       }
       catch(Exception e) {
 	throw new FileScanException(e, "Create new heapfile failed");
       }
       
       try {
 	  tscan = f.openTupleScan(target_colnums);
       }
       catch(Exception e){
 	throw new FileScanException(e, "openScan() failed");
       }
     }
   
   /////
    //@return shows what input fields go where in the output tuple
    ///
   public FldSpec[] show()
     {
       return perm_mat;
     }
   
   /////
    //@return the result tuple
    //@exception JoinsException some join exception
    //@exception IOException I/O errors
    //@exception InvalidTupleSizeException invalid tuple size
    //@exception InvalidTypeException tuple type not valid
    //@exception PageNotReadException exception from lower layer
    //@exception PredEvalException exception from PredEval class
    //@exception UnknowAttrType attribute type unknown
    //@exception FieldNumberOutOfBoundException array out of bounds
    //@exception WrongPermat exception for wrong FldSpec argument
    ///
   public Tuple get_next()
     throws JoinsException,
 	   IOException,
 	   InvalidTupleSizeException,
 	   InvalidTypeException,
 	   PageNotReadException, 
 	   PredEvalException,
 	   UnknowAttrType,
 	   FieldNumberOutOfBoundException,
 	   WrongPermat
     {     
       TID tid = new TID(this._Fstype.length);  //pass the length
       
       while(true) {
    	   try
    	   {
 	if((tuple1 =  tscan.getNext(tid)) == null) {
 	  return null;
 	}
 	
  	
 //	tuple1.setHdr(in1_len, _in1, s_sizes);
	tuple1.setHdr((short)_Fstype.length, _Fstype, _Fssize);
 	if (PredEval.Eval(OutputFilter, tuple1, null, _Fstype, null) == true){
 		//commented for target col name implementation
 	  //Projection.Project(tuple1, _Fstype,  Jtuple, perm_mat, nOutFlds);
 //		System.out.println("Tuple1");
// 		tuple1.print(_Fstype);
 	  return  tuple1;
// 	 return  Jtuple;
 	}        
       }
       
       catch(Exception e)
       {
       }
       
     }
     }
 
   /////
    //implement the abstract method close() from super class Iterator
    //to finish cleaning up
    ///
   public void close() 
     {
      
       if (!closeFlag) {
    	   try {
    		   tscan.closescan();
    		   closeFlag = true;
    	   }
    	   catch(Exception e)
    	   {}
       } 
     }
   
 }
 

///